package task

import (
	g "gogame/game"
	cfg "gogame/game/manage/config/structs"
	"gogame/lib"
	"strings"
)

/*
	任务基类
		FuncInitVal 返回任务初始值
		FuncGetVal  返回任务数值和任务检测值
		FuncChkCall 任务条件检测
		以上三个方法根据情况上层复写
*/

var taskList []*BaseTask

// LoadTask 加载所有任务
func LoadTask() {
	for _, task := range taskList {
		task.Run()
		taskStypeMap[task.Stype] = task
	}
}

func init() {
	LoadTask()
}

// defaultFuncInitVal 默认获取初始值方法
func defaultFuncInitVal(uid string, taskCon *cfg.GameTaskData) int32 {
	return 0
}

// defaultFuncGetVal 默认获取任务数值和任务检测值
func defaultFuncGetVal(uid string, args ...any) (int32, any) {
	return 1, 0
}

// defaultFuncChkCall 默认任务条件检测
func defaultFuncChkCall(cond int32, chkVal any) bool {
	if cond == 0 || cond == chkVal {
		return true
	}

	return false
}

// BaseTask 任务基类
type BaseTask struct {
	EventName string // 任务名  例：Task1->Task+任务stype
	Stype     int32  // 任务stype  直接取EventName的stype 省去手动填写
	IsInc     bool   // 累计还是覆盖 ture累加false覆盖

	FuncInitVal func(uid string, taskCon *cfg.GameTaskData) int32 // 返回任务初始值  根据情况复写
	FuncGetVal  func(uid string, args ...any) (int32, any)        // 返回任务数值和任务检测值  根据情况复写
	FuncChkCall func(cond int32, chkVal any) bool                 // 任务条件检测  根据情况复写
}

// NewTask 这里主要是为了统一载入taskList,在LoadTask的时候统一处理
func NewTask(task *BaseTask) *BaseTask {
	taskList = append(taskList, task)
	return task
}

// Run 开始任务
func (b *BaseTask) Run() {
	b.Stype = int32(lib.Convert.String2Int(strings.Split(b.EventName, "task")[1]))

	if b.FuncInitVal == nil {
		b.FuncInitVal = defaultFuncInitVal
	}
	if b.FuncGetVal == nil {
		b.FuncGetVal = defaultFuncGetVal
	}
	if b.FuncChkCall == nil {
		b.FuncChkCall = defaultFuncChkCall
	}

	b.EventOn()
}

// EventOn 任务事件监听
func (b *BaseTask) EventOn() {
	g.Event.On(b.EventName, b.EventDo)
}

// EventDo 任务事件执行
func (b *BaseTask) EventDo(uid string, args ...any) {
	_val, _chkVal := b.FuncGetVal(uid, args...)
	b.SetVal(uid, _val, _chkVal)
}

// FmtInitVal 格式化任务初始值,不可超过任务的PVal
func (b *BaseTask) FmtInitVal(initVal int32, taskCon *cfg.GameTaskData) int32 {
	_pVal := taskCon.Pval
	if initVal <= _pVal {
		return initVal
	} else {
		return _pVal
	}
}

// GetInitVal 获取任务初始值
func (b *BaseTask) GetInitVal(uid string, taskCon *cfg.GameTaskData) int32 {
	_initVal := b.FuncInitVal(uid, taskCon)
	return b.FmtInitVal(_initVal, taskCon)
}

// SetVal 设置任务值
func (b *BaseTask) SetVal(uid string, val int32, chkVal any) {
	g.M.Task.SetTaskVal(uid, b.Stype, val, chkVal, b.IsInc)
}
